import 'package:baselib/utils/log_util.dart';
import 'package:baselib/utils/time_util.dart';
import 'package:flutter/cupertino.dart';
import 'package:framelib/config/api_config.dart';
import 'package:framelib/utils/constant_util.dart';
import 'package:sp_util/sp_util.dart';
import 'dart:io';
import 'package:flutter_oss_aliyun/flutter_oss_aliyun.dart';

class OssUtil {
  static final OssUtil _singleton = OssUtil._internal();

  static OssUtil get instance => OssUtil();

  factory OssUtil() {
    return _singleton;
  }

  OssUtil._internal() {
    //做一些操作
  }

  String accessKeyId;
  String accessKeySecret;
  String securityToken;
  String expiration;

  init({
    dynamic credentials
  }) {
    this.accessKeyId = credentials?.accessKeyId;
    this.accessKeySecret = credentials?.accessKeySecret;
    this.securityToken = credentials?.securityToken;
    this.expiration = credentials?.expiration;
    LogUtil.d('OssUtil--->credentials=${credentials?.toString()}');
    Client.init(
        ossEndpoint: ApiConfig.oss_end_point,
        bucketName: ApiConfig.oss_bucket_name,
      authGetter: ()=>Auth(
        accessKey: this.accessKeyId,
        accessSecret: this.accessKeySecret,
        expire: this.expiration,
        secureToken: this.securityToken,
      ));
  }

  String getExtension(String path) {
    return path.substring(path.lastIndexOf("."));
  }

  String fileName() {
    // return DateFormat('yyyyMMddHHmmss').format(DateTime.now());
    return TimeUtils.forMatTimeByDateTime(DateTime.now(),
        format: 'yyyyMMddHHmmss');
  }

  String fileNameYearMonthDay() {
    // return DateFormat('yyyyMMdd').format(DateTime.now());
    return TimeUtils.forMatTimeByDateTime(DateTime.now(), format: 'yyyyMMdd');
  }

  String videoThumbnailSuffix() {
    return "?x-oss-process=video/snapshot,t_1000,f_jpg,w_0,h_0,m_fast,ar_auto";
  }

  Future getObjectKey(String filePath, File file) async {
    // final dateStr = DateFormat('yyMMdd').format(DateTime.now());
    final dateStr = TimeUtils.forMatTimeByDateTime(DateTime.now(), format: 'yyMMdd');

    print("dateStr =  $dateStr");

    // /u+userName
    var userNameU = "/u${SpUtil.getString(ConstantUtil.userId)}";
    print("userNameU =  $userNameU");

    // 获取十位数随机数
    var arcHashCode = (filePath?.hashCode ?? 0).abs();
    var arcHashCodeStr = arcHashCode.toString();

    print("arcHashCodeStr == $arcHashCodeStr");

    var decodedImage = await decodeImageFromList(file.readAsBytesSync());
    print(decodedImage.width);
    print(decodedImage.height);

    var widthAndheight =
        "(${decodedImage.width.toInt()}x${decodedImage.height.toInt()})";

    var objectKey = "$dateStr$userNameU$arcHashCodeStr${DateTime.now().millisecondsSinceEpoch}$widthAndheight";
    print("objectKey == $objectKey");
    return objectKey;
  }

  Future<String> getVideoWidthAndHeight(File file) async {
    int width;
    int height;
    // final FlutterFFprobe _flutterFFprobe = FlutterFFprobe();
    // var info = await _flutterFFprobe.getMediaInformation(file.path);

    // if (info.getStreams() != null) {
    //   List<dynamic>? streams = info.getStreams();
    //   if (streams!.isNotEmpty) {
    //     for (var stream in streams) {
    //       width = stream.getAllProperties()['width'];
    //       height = stream.getAllProperties()['height'];
    //     }
    //   }
    // }

    return "(${width}x$height)";
  }

  Future<void> upload(
    File file,
    {
      String prefix,
    void Function(String, bool) complete,
  }) async {
    // var imageName = fileName() + getExtension(file.path);
    var imageName = getExtension(file.path);
    var fullPath = file.path.replaceAll(RegExp('${file.path}\$'), imageName);

    String objectKey = await getObjectKey(fullPath, file);
    String path = "ios/" +
        ApiConfig.wyyx_app_id +
        "/${SpUtil.getString(ConstantUtil.userId)}" +
        '${prefix??''}$objectKey$imageName';

    // OSSImageObject ossObject =
    //     OSSImageObject.fromFile(file: file, uuid: '$prefix$name');

    var response = await Client()
        .putObject(
      file.readAsBytesSync(),
      path,
    ).catchError((onError) {
      if (complete != null) {
        complete(null, false);
      }
      print('Exception Error while putObject:' + onError.toString());
    });

    // String url = ossObject.resourcePath(path);
    String url =
        "https://${ApiConfig.oss_bucket_name}.${ApiConfig.oss_end_point}/$path";

    if (complete != null) {
      complete(url, true);
    }
  }

  Future<void> uploadVideo(
    File file, {
    void Function(String, bool) complete,
  }) async {
    String widthAndheight = await getVideoWidthAndHeight(file);
    var videoName = fileName() + getExtension(file.path);

    String path = "ios/" +
        ApiConfig.wyyx_app_id +
        "/${SpUtil.getString(ConstantUtil.userId)}" +
        videoName;

    // OSSVideoObject ossObject = OSSVideoObject.fromFile(file: file, uuid: name);

    await Client()
        .putObject(
      file.readAsBytesSync(),
      path,
    )
        .catchError((onError) {
      if (complete != null) {
        complete(null, false);
      }
      print('Exception Error while putObject:' + onError.toString());
    });

    // String url = ossObject.resourcePath(path);
    String url =
        "https://${ApiConfig.oss_bucket_name}.${ApiConfig.oss_end_point}/$path";

    if (complete != null) {
      complete(url, true);
    }
  }
}
